home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 748 / 748.xpi / content / utils.js < prev    next >
Text File  |  2010-02-11  |  13KB  |  445 lines

  1. const GM_GUID = "{e4a8a97b-f2ed-450b-b12d-ee082ba24781}";
  2.  
  3. // TODO: properly scope this constant
  4. const NAMESPACE = "http://youngpup.net/greasemonkey";
  5.  
  6. var GM_consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  7.                         .getService(Components.interfaces.nsIConsoleService);
  8.  
  9. function GM_isDef(thing) {
  10.   return typeof(thing) != "undefined";
  11. }
  12.  
  13. function GM_getConfig() {
  14.   return Components
  15.     .classes["@greasemonkey.mozdev.org/greasemonkey-service;1"]
  16.     .getService(Components.interfaces.gmIGreasemonkeyService)
  17.     .wrappedJSObject.config;
  18. }
  19.  
  20. function GM_hitch(obj, meth) {
  21.   if (!obj[meth]) {
  22.     throw "method '" + meth + "' does not exist on object '" + obj + "'";
  23.   }
  24.  
  25.   var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
  26.  
  27.   return function() {
  28.     // make a copy of staticArgs (don't modify it because it gets reused for
  29.     // every invocation).
  30.     var args = Array.prototype.slice.call(staticArgs);
  31.  
  32.     // add all the new arguments
  33.     Array.prototype.push.apply(args, arguments);
  34.  
  35.     // invoke the original function with the correct this obj and the combined
  36.     // list of static and dynamic arguments.
  37.     return obj[meth].apply(obj, args);
  38.   };
  39. }
  40.  
  41. function GM_listen(source, event, listener, opt_capture) {
  42.   Components.utils.lookupMethod(source, "addEventListener")(
  43.     event, listener, opt_capture);
  44. }
  45.  
  46. function GM_unlisten(source, event, listener, opt_capture) {
  47.   Components.utils.lookupMethod(source, "removeEventListener")(
  48.     event, listener, opt_capture);
  49. }
  50.  
  51. /**
  52.  * Utility to create an error message in the log without throwing an error.
  53.  */
  54. function GM_logError(e, opt_warn, fileName, lineNumber) {
  55.   var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  56.     .getService(Components.interfaces.nsIConsoleService);
  57.  
  58.   var consoleError = Components.classes["@mozilla.org/scripterror;1"]
  59.     .createInstance(Components.interfaces.nsIScriptError);
  60.  
  61.   var flags = opt_warn ? 1 : 0;
  62.  
  63.   // third parameter "sourceLine" is supposed to be the line, of the source,
  64.   // on which the error happened.  we don't know it. (directly...)
  65.   consoleError.init(e.message, fileName, null, lineNumber,
  66.                     e.columnNumber, flags, null);
  67.  
  68.   consoleService.logMessage(consoleError);
  69. }
  70.  
  71. function GM_log(message, force) {
  72.   if (force || GM_prefRoot.getValue("logChrome", false)) {
  73.     GM_consoleService.logStringMessage(message);
  74.   }
  75. }
  76.  
  77. function GM_openUserScriptManager() {
  78.   var win = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  79.                       .getService(Components.interfaces.nsIWindowMediator)
  80.                       .getMostRecentWindow("Greasemonkey:Manage");
  81.   if (win) {
  82.     win.focus();
  83.   } else {
  84.     var parentWindow = (!window.opener || window.opener.closed) ?
  85.       window : window.opener;
  86.     parentWindow.openDialog("chrome://greasemonkey/content/manage.xul",
  87.       "_blank", "resizable,dialog=no,centerscreen");
  88.   }
  89. }
  90.  
  91. // TODO: this stuff was copied wholesale and not refactored at all. Lots of
  92. // the UI and Config rely on it. Needs rethinking.
  93.  
  94. function openInEditor(script) {
  95.   var file = script.editFile;
  96.   var stringBundle = Components
  97.     .classes["@mozilla.org/intl/stringbundle;1"]
  98.     .getService(Components.interfaces.nsIStringBundleService)
  99.     .createBundle("chrome://greasemonkey/locale/gm-browser.properties");
  100.   var editor = getEditor(stringBundle);
  101.   if (!editor) {
  102.     // The user did not choose an editor.
  103.     return;
  104.   }
  105.  
  106.   try {
  107.     launchApplicationWithDoc(editor, file);
  108.   } catch (e) {
  109.     // Something may be wrong with the editor the user selected. Remove so that
  110.     // next time they can pick a different one.
  111.     alert(stringBundle.GetStringFromName("editor.could_not_launch") + "\n" + e);
  112.     GM_prefRoot.remove("editor");
  113.     throw e;
  114.   }
  115. }
  116.  
  117. function getEditor(stringBundle) {
  118.   var editorPath = GM_prefRoot.getValue("editor");
  119.  
  120.   if (editorPath) {
  121.     GM_log("Found saved editor preference: " + editorPath);
  122.  
  123.     var editor = Components.classes["@mozilla.org/file/local;1"]
  124.                  .createInstance(Components.interfaces.nsILocalFile);
  125.     editor.followLinks = true;
  126.     editor.initWithPath(editorPath);
  127.  
  128.     // make sure the editor preference is still valid
  129.     if (editor.exists() && editor.isExecutable()) {
  130.       return editor;
  131.     } else {
  132.       GM_log("Editor preference either does not exist or is not executable");
  133.       GM_prefRoot.remove("editor");
  134.     }
  135.   }
  136.  
  137.   // Ask the user to choose a new editor. Sometimes users get confused and
  138.   // pick a non-executable file, so we set this up in a loop so that if they do
  139.   // that we can give them an error and try again.
  140.   while (true) {
  141.     GM_log("Asking user to choose editor...");
  142.     var nsIFilePicker = Components.interfaces.nsIFilePicker;
  143.     var filePicker = Components.classes["@mozilla.org/filepicker;1"]
  144.                                .createInstance(nsIFilePicker);
  145.  
  146.     filePicker.init(window, stringBundle.GetStringFromName("editor.prompt"),
  147.                     nsIFilePicker.modeOpen);
  148.     filePicker.appendFilters(nsIFilePicker.filterApplication);
  149.     filePicker.appendFilters(nsIFilePicker.filterAll);
  150.  
  151.     if (filePicker.show() != nsIFilePicker.returnOK) {
  152.       // The user canceled, return null.
  153.       GM_log("User canceled file picker dialog");
  154.       return null;
  155.     }
  156.  
  157.     GM_log("User selected: " + filePicker.file.path);
  158.  
  159.     if (filePicker.file.exists() && filePicker.file.isExecutable()) {
  160.       GM_prefRoot.setValue("editor", filePicker.file.path);
  161.       return filePicker.file;
  162.     } else {
  163.       alert(stringBundle.GetStringFromName("editor.please_pick_executable"));
  164.     }
  165.   }
  166. }
  167.  
  168. function launchApplicationWithDoc(appFile, docFile) {
  169.   var args=[docFile.path];
  170.  
  171.   // For the mac, wrap with a call to "open".
  172.   var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
  173.                              .getService(Components.interfaces.nsIXULRuntime);
  174.   if ("Darwin"==xulRuntime.OS) {
  175.     args=["-a", appFile.path, docFile.path]
  176.  
  177.     appFile = Components.classes["@mozilla.org/file/local;1"]
  178.                         .createInstance(Components.interfaces.nsILocalFile);
  179.     appFile.followLinks = true;
  180.     appFile.initWithPath("/usr/bin/open");
  181.   }
  182.  
  183.   var process = Components.classes["@mozilla.org/process/util;1"]
  184.                           .createInstance(Components.interfaces.nsIProcess);
  185.   process.init(appFile);
  186.   process.run(false, args, args.length);
  187. }
  188.  
  189. function parseScriptName(sourceUri) {
  190.   var name = sourceUri.spec;
  191.   name = name.substring(0, name.indexOf(".user.js"));
  192.   name = name.substring(name.lastIndexOf("/") + 1);
  193.   return name;
  194. }
  195.  
  196. function getTempFile() {
  197.   var file = Components.classes["@mozilla.org/file/directory_service;1"]
  198.         .getService(Components.interfaces.nsIProperties)
  199.         .get("TmpD", Components.interfaces.nsILocalFile);
  200.  
  201.   file.append("gm-temp");
  202.   file.createUnique(
  203.     Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,
  204.     0640
  205.   );
  206.  
  207.   return file;
  208. }
  209.  
  210. function getBinaryContents(file) {
  211.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  212.                               .getService(Components.interfaces.nsIIOService);
  213.  
  214.     var channel = ioService.newChannelFromURI(GM_getUriFromFile(file));
  215.     var input = channel.open();
  216.  
  217.     var bstream = Components.classes["@mozilla.org/binaryinputstream;1"]
  218.                             .createInstance(Components.interfaces.nsIBinaryInputStream);
  219.     bstream.setInputStream(input);
  220.  
  221.     var bytes = bstream.readBytes(bstream.available());
  222.  
  223.     return bytes;
  224. }
  225.  
  226. function getContents(file, charset) {
  227.   if( !charset ) {
  228.     charset = "UTF-8"
  229.   }
  230.   var ioService=Components.classes["@mozilla.org/network/io-service;1"]
  231.     .getService(Components.interfaces.nsIIOService);
  232.   var scriptableStream=Components
  233.     .classes["@mozilla.org/scriptableinputstream;1"]
  234.     .getService(Components.interfaces.nsIScriptableInputStream);
  235.   // http://lxr.mozilla.org/mozilla/source/intl/uconv/idl/nsIScriptableUConv.idl
  236.   var unicodeConverter = Components
  237.     .classes["@mozilla.org/intl/scriptableunicodeconverter"]
  238.     .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  239.   unicodeConverter.charset = charset;
  240.  
  241.   var channel = ioService.newChannelFromURI(GM_getUriFromFile(file));
  242.   var input=channel.open();
  243.   scriptableStream.init(input);
  244.   var str=scriptableStream.read(input.available());
  245.   scriptableStream.close();
  246.   input.close();
  247.  
  248.   try {
  249.     return unicodeConverter.ConvertToUnicode(str);
  250.   } catch( e ) {
  251.     return str;
  252.   }
  253. }
  254.  
  255. function getWriteStream(file) {
  256.   var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
  257.                          .createInstance(Components.interfaces.nsIFileOutputStream);
  258.  
  259.   stream.init(file, 0x02 | 0x08 | 0x20, 420, -1);
  260.  
  261.   return stream;
  262. }
  263.  
  264. function GM_getUriFromFile(file) {
  265.   return Components.classes["@mozilla.org/network/io-service;1"]
  266.                    .getService(Components.interfaces.nsIIOService)
  267.                    .newFileURI(file);
  268. }
  269.  
  270. /**
  271.  * Compares two version numbers
  272.  *
  273.  * @param {String} aV1 Version of first item in 1.2.3.4..9. format
  274.  * @param {String} aV2 Version of second item in 1.2.3.4..9. format
  275.  *
  276.  * @returns {Int}  1 if first argument is higher
  277.  *                 0 if arguments are equal
  278.  *                 -1 if second argument is higher
  279.  */
  280. function GM_compareVersions(aV1, aV2) {
  281.   var v1 = aV1.split(".");
  282.   var v2 = aV2.split(".");
  283.   var numSubversions = (v1.length > v2.length) ? v1.length : v2.length;
  284.  
  285.   for (var i = 0; i < numSubversions; i++) {
  286.     if (typeof v2[i] == "undefined") {
  287.       return 1;
  288.     }
  289.  
  290.     if (typeof v1[i] == "undefined") {
  291.       return -1;
  292.     }
  293.  
  294.     if (parseInt(v2[i], 10) > parseInt(v1[i], 10)) {
  295.       return -1;
  296.     } else if (parseInt(v2[i], 10) < parseInt(v1[i], 10)) {
  297.       return 1;
  298.     }
  299.   }
  300.  
  301.   // v2 was never higher or lower than v1
  302.   return 0;
  303. }
  304.  
  305. /**
  306.  * Takes the place of the traditional prompt() function which became broken
  307.  * in FF 1.0.1. :(
  308.  */
  309. function gmPrompt(msg, defVal, title) {
  310.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  311.                                 .getService(Components.interfaces.nsIPromptService);
  312.   var result = {value:defVal};
  313.  
  314.   if (promptService.prompt(null, title, msg, result, null, {value:0})) {
  315.     return result.value;
  316.   }
  317.   else {
  318.     return null;
  319.   }
  320. }
  321.  
  322. function ge(id) {
  323.   return window.document.getElementById(id);
  324. }
  325.  
  326.  
  327. function dbg(o) {
  328.   var s = "";
  329.   var i = 0;
  330.  
  331.   for (var p in o) {
  332.     s += p + ":" + o[p] + "\n";
  333.  
  334.     if (++i % 15 == 0) {
  335.       alert(s);
  336.       s = "";
  337.     }
  338.   }
  339.  
  340.   alert(s);
  341. }
  342.  
  343. function delaydbg(o) {
  344.   setTimeout(function() {dbg(o);}, 1000);
  345. }
  346.  
  347. function delayalert(s) {
  348.   setTimeout(function() {alert(s);}, 1000);
  349. }
  350.  
  351. function GM_isGreasemonkeyable(url) {
  352.   var scheme = Components.classes["@mozilla.org/network/io-service;1"]
  353.                .getService(Components.interfaces.nsIIOService)
  354.                .extractScheme(url);
  355.  
  356.   if ("http" == scheme) return true;
  357.   if ("https" == scheme) return true;
  358.   if ("ftp" == scheme) return true;
  359.   if ("data" == scheme) return true;
  360.  
  361.   if ("file" == scheme) {
  362.     return GM_prefRoot.getValue('fileIsGreaseable');
  363.   }
  364.  
  365.   if ("about" == scheme) {
  366.     // Always allow "about:blank".
  367.     if (/^about:blank/.test(url)) return true;
  368.  
  369.     // Conditionally allow the rest of "about:".
  370.     return GM_prefRoot.getValue('aboutIsGreaseable');
  371.   }
  372.  
  373.   return false;
  374. }
  375.  
  376. function GM_isFileScheme(url) {
  377.   var scheme = Components.classes["@mozilla.org/network/io-service;1"]
  378.                .getService(Components.interfaces.nsIIOService)
  379.                .extractScheme(url);
  380.  
  381.   return scheme == "file";
  382. }
  383.  
  384. function GM_getEnabled() {
  385.   return GM_prefRoot.getValue("enabled", true);
  386. }
  387.  
  388. function GM_setEnabled(enabled) {
  389.   GM_prefRoot.setValue("enabled", enabled);
  390. }
  391.  
  392.  
  393. /**
  394.  * Logs a message to the console. The message can have python style %s
  395.  * thingers which will be interpolated with additional parameters passed.
  396.  */
  397. function log(message) {
  398.   if (GM_prefRoot.getValue("logChrome", false)) {
  399.     logf.apply(null, arguments);
  400.   }
  401. }
  402.  
  403. function logf(message) {
  404.   for (var i = 1; i < arguments.length; i++) {
  405.     message = message.replace(/\%s/, arguments[i]);
  406.   }
  407.  
  408.   dump(message + "\n");
  409. }
  410.  
  411. /**
  412.  * Loggifies an object. Every method of the object will have it's entrance,
  413.  * any parameters, any errors, and it's exit logged automatically.
  414.  */
  415. function loggify(obj, name) {
  416.   for (var p in obj) {
  417.     if (typeof obj[p] == "function") {
  418.       obj[p] = gen_loggify_wrapper(obj[p], name, p);
  419.     }
  420.   }
  421. }
  422.  
  423. function gen_loggify_wrapper(meth, objName, methName) {
  424.   return function() {
  425.      var retVal;
  426.     //var args = new Array(arguments.length);
  427.     var argString = "";
  428.     for (var i = 0; i < arguments.length; i++) {
  429.       //args[i] = arguments[i];
  430.       argString += arguments[i] + (((i+1)<arguments.length)? ", " : "");
  431.     }
  432.  
  433.     log("> %s.%s(%s)", objName, methName, argString); //args.join(", "));
  434.  
  435.     try {
  436.       return retVal = meth.apply(this, arguments);
  437.     } finally {
  438.       log("< %s.%s: %s",
  439.           objName,
  440.           methName,
  441.           (typeof retVal == "undefined" ? "void" : retVal));
  442.     }
  443.   }
  444. }
  445.